<?php
/**
 * Ext.Direct config Ini generator
 * inspired by symfony's Ext Direct plugin
 *
 * @author Daniel Gasparotto <daniel.gasparotto@gmail.com>
 *
 */
class Beaver_Config_Writer_Ini extends Zend_Config_Writer_Ini {

    private $api = array();

    public function __construct($fname) {

        $this->grepDirect(APPLICATION_PATH.'/controllers');

        // create config sections
        $config = new Zend_Config(array('production'=> $this->api), true);
        $config->staging = array();
        $config->setExtend('staging', 'production');
        $config->development = array();
        $config->setExtend('development', 'production');
        $config->testing = array();
        $config->setExtend('testing', 'production');

        parent::__construct(array('config' => $config, 'filename' => $fname ));

    }

    private function grepDirect($path) {

        // get all controllers from APPLICATION_PATH
        $q = '/class(.*)Controller(.*)extends(.*)_Controller_Action/';
        if( preg_match("#^\.#", $path) ) continue;

        $fp = opendir($path);
        while($f = readdir($fp)) {
            if( preg_match("#^\.#", $f) )  continue;

            $file_full_path = $path.'/'.$f;

            // no sub folders (modules) for now...
            /*if(is_dir($file_full_path)) {
                $this->grepDirect( $file_full_path);
                continue;
            }*/

            $matches = array();
            if(preg_match($q, file_get_contents($file_full_path),$matches)) {
                $controller = trim($matches[1]);
                $className = $controller.'Controller';

                // uses the ZF autoloader
                require_once($file_full_path);
                
                $class = new ReflectionClass($className);

                $class_comments = $class->getDocComment();


                // Controller-level, CRUD Ext.Direct (generates the 4 methods)

                if(strpos($class_comments, '@extdirect-crud') !== false) {

                    $this->api['ExtDirect']['Remote'][] = array(
                            'controller' => $controller,
                            'action'     => 'read',
                            'attributes' => 1,
                            'formHandler'=> false
                    );
                    $this->api['ExtDirect']['Remote'][] = array(
                            'controller' => $controller,
                            'action'     => 'update',
                            'attributes' => 1,
                            'formHandler'=> false
                    );
                    $this->api['ExtDirect']['Remote'][] = array(
                            'controller' => $controller,
                            'action'     => 'create',
                            'attributes' => 1,
                            'formHandler'=> false
                    );
                    $this->api['ExtDirect']['Remote'][] = array(
                            'controller' => $controller,
                            'action'     => 'destroy',
                            'attributes' => 1,
                            'formHandler'=> false
                    );

                }


                /*
                 * Action-level Ext.Direct methods
                 * Accepts extdirect-enable, extdirect-len, extdirect-formHandler
                */

                foreach($class->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
                    if(strpos($method->getName(),'Action')===false) continue;

                    // retrieve annotations
                    $method_comments = $method->getDocComment();
                    if(strpos($method_comments, '@extdirect-enable') !== false) {

                        $method_name = $method->getName();
                        $method_name = substr($method_name, 0, count($method_name)-7);

                        preg_match('/@extdirect-len (?P<len>\\d*)/', $method_comments, $method_len);
                        $method_len = isset($method_len['len']) && !empty($method_len['len']) ? $method_len['len'] : 0;
                        $method_fh = strpos($method_comments, '@extdirect-formHandler') !== false ? true : false;

                        $this->api['ExtDirect']['Remote'][] = array(
                                'controller' => $controller,
                                'action'     => $method_name,
                                'attributes' => $method_len,
                                'formHandler'=> $method_fh
                        );
                    }
                }
            }
        }
    }
}